// =============================================================
// static/app.js  — 支持多文件上传并发队列 + 美化进度条 + 问答
// =============================================================

// ---------- DOM 辅助 ----------
const fileInput   = document.getElementById("file");
const submitBtn   = document.getElementById("submit");
const errorBox    = document.getElementById("error");
const resultBox   = document.getElementById("result");
const answerBox   = document.getElementById("answer");

let uploadList = document.getElementById("uploadList");
if (!uploadList) {
  uploadList = document.createElement("div");
  uploadList.id = "uploadList";
  uploadList.style.marginTop = "1rem";
  document.querySelector(".container").insertBefore(uploadList, resultBox);
}

// ---------- 上传并发队列 ----------
const MAX_CONCURRENT = 3;
let activeUploads = 0;
const uploadQueue = [];

fileInput.addEventListener("change", () => {
  const files = Array.from(fileInput.files || []);
  if (!files.length) return;
  files.forEach(f => uploadQueue.push(f));
  processQueue();
});

function processQueue() {
  while (uploadQueue.length && activeUploads < MAX_CONCURRENT) {
    const file = uploadQueue.shift();
    activeUploads++;
    uploadFile(file).finally(() => {
      activeUploads--;
      processQueue();
    });
  }
}

// ---------- 上传 + 动画进度条 ----------
function uploadFile(file) {
  return new Promise((resolve) => {
    const item = document.createElement("div");
    item.className = "upload-item";
    item.style.marginBottom = "0.5rem";
    item.innerHTML = `
      <div style="font-size:.9rem;margin-bottom:0.3rem;">📄 ${file.name}</div>
      <div class="progress-container" style="width:100%;height:12px;background:#333;border-radius:6px;overflow:hidden;">
        <div class="progress-bar" style="height:100%;width:0%;background:linear-gradient(to right, #4f7eff, #00c4ff);
             transition: width 0.2s ease;"></div>
      </div>`;
    uploadList.appendChild(item);
    const bar = item.querySelector(".progress-bar");

    const xhr = new XMLHttpRequest();
    xhr.open("POST", "/api/ask", true);

    xhr.upload.onprogress = (e) => {
      if (e.lengthComputable) {
        const percent = Math.round((e.loaded / e.total) * 100);
        bar.style.width = percent + "%";
      }
    };

    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        bar.style.width = "100%";
        setTimeout(() => item.remove(), 1000);
        if (xhr.status === 200) {
          try {
            const data = JSON.parse(xhr.responseText);
            handleServerResponse(data);
          } catch {
            showError("❌ 解析服务器响应失败");
          }
        } else {
          showError("❌ 上传失败：" + xhr.status);
        }
        resolve();
      }
    };

    const fd = new FormData();
    fd.append("question", "构建知识图谱");
    fd.append("file", file);
    xhr.send(fd);
  });
}

// ---------- 提问逻辑 ----------
submitBtn.addEventListener("click", async () => {
  const question = document.getElementById("question").value.trim();
  if (!question) return showError("❌ 问题不能为空");

  showLoading("处理中...");
  const fd = new FormData();
  fd.append("question", question);

  try {
    const res  = await fetch("/api/ask", { method: "POST", body: fd });
    const data = await res.json();
    handleServerResponse(data);
  } catch {
    showError("❌ 请求失败");
  } finally {
    hideLoading();
  }
});

// ---------- 处理服务器返回 ----------
function handleServerResponse(data) {
  if (data.error) return showError(data.error);
  resultBox.style.display = "block";
  answerBox.textContent  = data.answer;
  renderChatHistory(data.history || []);
  drawKG(data.triples || []);
  errorBox.textContent = "";
}

// ---------- 聊天记录 ----------
function renderChatHistory(hist) {
  const box = document.getElementById("chatHistory");
  box.innerHTML = "<h3>📝 对话历史</h3>" + hist.map(it => `
    <div><strong>🧑 用户：</strong>${it.q}</div>
    <div><strong>🤖 助手：</strong>${it.a}</div>
    <hr style="border-color:#333">`).join("");
}

// ---------- D3 绘图 ----------
function drawKG(triples) {
  const svg = d3.select("#kgGraph");
  svg.selectAll("*").remove();
  if (!triples.length) return;
  const W = +svg.attr("width"), H = +svg.attr("height");
  const nodes = [...new Set(triples.flatMap(t => [t.source, t.target]))].map(id => ({ id }));
  const links = triples.map(t => ({ source: t.source, target: t.target, label: t.relation }));

  const sim = d3.forceSimulation(nodes)
    .force("link", d3.forceLink(links).id(d => d.id).distance(120))
    .force("charge", d3.forceManyBody().strength(-300))
    .force("center", d3.forceCenter(W / 2, H / 2));

  const link = svg.append("g").selectAll("line")
    .data(links).enter().append("line")
    .attr("stroke", "#888").attr("stroke-width", 1.5);

  const node = svg.append("g").selectAll("circle")
    .data(nodes).enter().append("circle")
    .attr("r", 8).attr("fill", "#4f7eff")
    .on("click", (_, d) => showNodeDetails(d.id));

  svg.append("g").selectAll("text").data(nodes).enter()
     .append("text").text(d => d.id).attr("font-size", "10px").attr("fill", "#eee");

  sim.on("tick", () => {
    link.attr("x1", d => d.source.x).attr("y1", d => d.source.y)
        .attr("x2", d => d.target.x).attr("y2", d => d.target.y);
    node.attr("cx", d => d.x).attr("cy", d => d.y);
    svg.selectAll("text").attr("x", d => d.x + 10).attr("y", d => d.y);
  });
}

// ---------- 节点详情浮窗 ----------
function showNodeDetails(id) {
  let panel = document.getElementById("nodeInfo");
  if (!panel) {
    panel = document.createElement("div");
    panel.id = "nodeInfo";
    panel.style.cssText = "position:fixed;top:2rem;right:2rem;padding:1rem;background:#222;color:#fff;border:1px solid #444;border-radius:8px;max-width:200px;z-index:999";
    document.body.appendChild(panel);
  }
  panel.innerHTML = `<strong>🔍 节点:</strong><br>${id}`;
}

// ---------- Loading 遮罩 ----------
function showLoading(msg) {
  let overlay = document.getElementById("loadingOverlay");
  if (!overlay) {
    overlay = document.createElement("div");
    overlay.id = "loadingOverlay";
    overlay.style.cssText = "position:fixed;inset:0;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;color:#fff;font-size:1.4rem;z-index:1000";
    document.body.appendChild(overlay);
  }
  overlay.textContent = msg;
  overlay.style.display = "flex";
}
function hideLoading() {
  const overlay = document.getElementById("loadingOverlay");
  if (overlay) overlay.style.display = "none";
}
function showError(msg) { errorBox.textContent = msg; }

// ---------- 初始加载上传历史 ----------
fetch("/api/uploads").then(r => r.json()).then(list => {
  if (!list.length) return;
  const cont = document.createElement("div");
  cont.innerHTML = `<h3>📂 上传历史</h3>${list.map(r => `<div>${r.filename} <small>${r.timestamp}</small></div>`).join("")}`;
  document.querySelector(".container").appendChild(cont);
});
